Have GdkWindowImplQuartz implement GdkPaintable.
authorAnders Carlsson <andersca@mac.imendio.com>
Mon, 10 Apr 2006 23:17:26 +0000 (23:17 +0000)
committerAnders Carlsson <andersca@src.gnome.org>
Mon, 10 Apr 2006 23:17:26 +0000 (23:17 +0000)
2006-04-11  Anders Carlsson  <andersca@mac.imendio.com>

        * gdk/quartz/GdkQuartzView.c:
        (-[GdkQuartzView drawRect:]):
        * gdk/quartz/gdkdrawable-quartz.c:
        (gdk_quartz_ref_cairo_surface):
        (_gdk_quartz_drawable_get_context):
        (_gdk_quartz_drawable_release_context):
        * gdk/quartz/gdkwindow-quartz.c:
        (gdk_window_impl_quartz_finalize):
        (gdk_window_impl_quartz_class_init):
        (gdk_window_impl_quartz_begin_paint_region):
        (gdk_window_impl_quartz_end_paint):
        (gdk_window_impl_quartz_invalidate_maybe_recurse):
        (gdk_window_impl_quartz_process_updates):
        (gdk_window_impl_quartz_paintable_init):
        (_gdk_window_impl_quartz_get_type):
        * gdk/quartz/gdkwindow-quartz.h:
        Have GdkWindowImplQuartz implement GdkPaintable.

ChangeLog
ChangeLog.pre-2-10
gdk/quartz/GdkQuartzView.c
gdk/quartz/gdkdrawable-quartz.c
gdk/quartz/gdkwindow-quartz.c
gdk/quartz/gdkwindow-quartz.h

index 9c76485e7c1b0197fa75c0323dfc5e4ebf372117..e5870a0984a14c498d97b83f6e9b6aea1f6d2e1b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2006-04-11  Anders Carlsson  <andersca@mac.imendio.com>
+
+        * gdk/quartz/GdkQuartzView.c:
+        (-[GdkQuartzView drawRect:]):
+        * gdk/quartz/gdkdrawable-quartz.c:
+        (gdk_quartz_ref_cairo_surface):
+        (_gdk_quartz_drawable_get_context):
+        (_gdk_quartz_drawable_release_context):
+        * gdk/quartz/gdkwindow-quartz.c:
+        (gdk_window_impl_quartz_finalize):
+        (gdk_window_impl_quartz_class_init):
+        (gdk_window_impl_quartz_begin_paint_region):
+        (gdk_window_impl_quartz_end_paint):
+        (gdk_window_impl_quartz_invalidate_maybe_recurse):
+        (gdk_window_impl_quartz_process_updates):
+        (gdk_window_impl_quartz_paintable_init):
+        (_gdk_window_impl_quartz_get_type):
+        * gdk/quartz/gdkwindow-quartz.h:
+        Have GdkWindowImplQuartz implement GdkPaintable.
+
 2006-04-10  Michael Natterer  <mitch@imendio.com>
 
        * gtk/gtktextbufferrichtext.c (gtk_text_buffer_deserialize):
index 9c76485e7c1b0197fa75c0323dfc5e4ebf372117..e5870a0984a14c498d97b83f6e9b6aea1f6d2e1b 100644 (file)
@@ -1,3 +1,23 @@
+2006-04-11  Anders Carlsson  <andersca@mac.imendio.com>
+
+        * gdk/quartz/GdkQuartzView.c:
+        (-[GdkQuartzView drawRect:]):
+        * gdk/quartz/gdkdrawable-quartz.c:
+        (gdk_quartz_ref_cairo_surface):
+        (_gdk_quartz_drawable_get_context):
+        (_gdk_quartz_drawable_release_context):
+        * gdk/quartz/gdkwindow-quartz.c:
+        (gdk_window_impl_quartz_finalize):
+        (gdk_window_impl_quartz_class_init):
+        (gdk_window_impl_quartz_begin_paint_region):
+        (gdk_window_impl_quartz_end_paint):
+        (gdk_window_impl_quartz_invalidate_maybe_recurse):
+        (gdk_window_impl_quartz_process_updates):
+        (gdk_window_impl_quartz_paintable_init):
+        (_gdk_window_impl_quartz_get_type):
+        * gdk/quartz/gdkwindow-quartz.h:
+        Have GdkWindowImplQuartz implement GdkPaintable.
+
 2006-04-10  Michael Natterer  <mitch@imendio.com>
 
        * gtk/gtktextbufferrichtext.c (gtk_text_buffer_deserialize):
index 979e0e354e4aaef5c152f5e42dbd3969228d64fb..e4089aceb2b6ccb43e3057bd5846a49a961c9fb5 100644 (file)
 {
   NSRect bounds = [self bounds];
   GdkRectangle gdk_rect;
+  GdkWindowObject *private = GDK_WINDOW_OBJECT (gdk_window);
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl);
 
   GDK_QUARTZ_ALLOC_POOL;
 
-  /* Draw background */
-  if (GDK_WINDOW_OBJECT (gdk_window)->bg_pixmap == NULL)
+  gdk_rect.x = rect.origin.x;
+  gdk_rect.y = rect.origin.y;
+  gdk_rect.width = rect.size.width;
+  gdk_rect.height = rect.size.height;
+  
+  if (private->event_mask & GDK_EXPOSURE_MASK)
     {
-      CGContextRef context;
-
-      context = [[NSGraphicsContext currentContext] graphicsPort];
-      CGContextSaveGState (context);
-
-      _gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (gdk_window),
-                                                   GDK_WINDOW_OBJECT (gdk_window)->bg_color.pixel);
-
-      CGContextFillRect (context, CGRectMake (bounds.origin.x, bounds.origin.y,
-                                            bounds.size.width, bounds.size.height));
-      CGContextRestoreGState (context);
+      GdkEvent event;
+      
+      event.expose.type = GDK_EXPOSE;
+      event.expose.window = g_object_ref (gdk_window);
+      event.expose.send_event = FALSE;
+      event.expose.count = 0;
+      event.expose.region = gdk_region_rectangle (&gdk_rect);
+      event.expose.area = gdk_rect;
+    
+      impl->in_paint_rect_count ++;
+
+      (*_gdk_event_func) (&event, _gdk_event_data);
+
+      impl->in_paint_rect_count --;
+
+      g_object_unref (gdk_window);
+      gdk_region_destroy (event.expose.region);
     }
 
-  gdk_rect.x = bounds.origin.x;
-  gdk_rect.y = bounds.origin.y;
-  gdk_rect.width = bounds.size.width;
-  gdk_rect.height = bounds.size.height;
-  
-  gdk_window_invalidate_rect (gdk_window, &gdk_rect, FALSE);
-  gdk_window_process_updates (gdk_window, FALSE);
-
   GDK_QUARTZ_RELEASE_POOL;
 }
 
index 4f2b136e29ff309291bee40d1121a35a661122df..6e5cdd852537566b0962a6636ad3d7f48cf9d25c 100644 (file)
@@ -61,7 +61,7 @@ gdk_quartz_ref_cairo_surface (GdkDrawable *drawable)
 
   gdk_drawable_get_size (drawable, &width, &height);
 
-  surface = cairo_quartz_surface_create (context, TRUE, width, height);
+  surface = cairo_quartz_surface_create (context, width, height, TRUE);
 
   info = g_new (SurfaceInfo, 1);
   info->drawable = drawable;
@@ -586,6 +586,37 @@ _gdk_quartz_drawable_get_context (GdkDrawable *drawable, gboolean antialias)
       CGContextSaveGState (context);
       CGContextSetAllowsAntialiasing (context, antialias);
 
+      /* We'll emulate the clipping caused by double buffering here */
+      if (impl->begin_paint_count != 0)
+       {
+         CGRect rect;
+         CGRect *cg_rects;
+         GdkRectangle *rects;
+         gint n_rects, i;
+         
+         gdk_region_get_rectangles (impl->paint_clip_region,
+                                    &rects, &n_rects);
+         
+         if (n_rects == 1)
+           cg_rects = &rect;
+         else
+           cg_rects = g_new (CGRect, n_rects);
+         
+         for (i = 0; i < n_rects; i++)
+           {
+             cg_rects[i].origin.x = rects[i].x;
+             cg_rects[i].origin.y = rects[i].y;
+             cg_rects[i].size.width = rects[i].width;
+             cg_rects[i].size.height = rects[i].height;
+           }
+         
+         CGContextClipToRects (context, cg_rects, n_rects);
+         
+         g_free (rects);
+         if (cg_rects != &rect)
+           g_free (cg_rects);
+       }
+      
       return context;
     }
   else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable))
@@ -623,7 +654,9 @@ _gdk_quartz_drawable_release_context (GdkDrawable *drawable, CGContextRef contex
       CGContextRestoreGState (context);
       CGContextSetAllowsAntialiasing (context, TRUE);
 
-      [[NSGraphicsContext currentContext] flushGraphics];
+      if (impl->in_paint_rect_count == 0)
+       CGContextFlush (context);
+
       [impl->view unlockFocus];
       [impl->pool release];
     }
index 1f39743f97307fafdf53fd6762e947e099288e33..92c915c9d37170561cb93bd5bedac32ee50b8221 100644 (file)
@@ -105,6 +105,9 @@ gdk_window_impl_quartz_finalize (GObject *object)
   if (impl->nscursor)
     [impl->nscursor release];
 
+  if (impl->paint_clip_region)
+    gdk_region_destroy (impl->paint_clip_region);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -112,9 +115,12 @@ static void
 gdk_window_impl_quartz_class_init (GdkWindowImplQuartzClass *klass)
 {
   GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   parent_class = g_type_class_peek_parent (klass);
 
+  object_class->finalize = gdk_window_impl_quartz_finalize;
+
   drawable_class->get_size = gdk_window_impl_quartz_get_size;
 
   /* Visible and clip regions are the same */
@@ -130,6 +136,89 @@ gdk_window_impl_quartz_init (GdkWindowImplQuartz *impl)
   impl->height = 1;
 }
 
+static void
+gdk_window_impl_quartz_begin_paint_region (GdkPaintable *paintable,
+                                          GdkRegion    *region)
+{
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
+  CGContextRef context = _gdk_quartz_drawable_get_context (GDK_DRAWABLE (impl), FALSE);
+  int i, n_rects;
+  GdkRectangle *rects;
+
+  if (impl->begin_paint_count == 0)
+    impl->paint_clip_region = gdk_region_copy (region);
+  else
+    gdk_region_union (impl->paint_clip_region, region);
+
+  impl->begin_paint_count ++;
+
+  gdk_region_get_rectangles (region, &rects, &n_rects);
+  for (i = 0; i < n_rects; i++) 
+    {
+      _gdk_quartz_set_context_fill_color_from_pixel (context, gdk_drawable_get_colormap (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper),
+                                                    GDK_WINDOW_OBJECT (GDK_DRAWABLE_IMPL_QUARTZ (impl)->wrapper)->bg_color.pixel);
+      
+      CGContextFillRect (context, CGRectMake (rects[i].x, rects[i].y, rects[i].width, rects[i].height));
+      
+    }
+  g_free (rects);
+
+  _gdk_quartz_drawable_release_context (GDK_DRAWABLE (impl), context);
+}
+
+static void
+gdk_window_impl_quartz_end_paint (GdkPaintable *paintable)
+{
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
+
+  impl->begin_paint_count --;
+}
+
+static void
+gdk_window_impl_quartz_invalidate_maybe_recurse (GdkPaintable *paintable,
+                                                GdkRegion    *region,
+                                                gboolean    (*child_func) (GdkWindow *, gpointer),
+                                                gpointer      user_data)
+{
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
+  int i, n_rects;
+  GdkRectangle *rects;
+
+  gdk_region_get_rectangles (region, &rects, &n_rects);
+
+  for (i = 0; i < n_rects; i++) 
+    {
+      [impl->view setNeedsDisplayInRect:NSMakeRect (rects[i].x, rects[i].y,
+                                                   rects[i].width, rects[i].height)];
+    }
+
+  g_free (rects);
+
+  /* FIXME: Check if we need to traverse the children */
+}
+
+static void
+gdk_window_impl_quartz_process_updates (GdkPaintable *paintable,
+                                       gboolean      update_children)
+{
+  GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (paintable);
+
+  [impl->view display];
+
+  /* FIXME: Check if display actually updates the children too */
+}
+
+static void
+gdk_window_impl_quartz_paintable_init (GdkPaintableIface *iface)
+{
+  iface->begin_paint_region = gdk_window_impl_quartz_begin_paint_region;
+  iface->end_paint = gdk_window_impl_quartz_end_paint;
+
+  iface->invalidate_maybe_recurse = gdk_window_impl_quartz_invalidate_maybe_recurse;
+  iface->process_updates = gdk_window_impl_quartz_process_updates;
+}
+
+
 GType
 _gdk_window_impl_quartz_get_type (void)
 {
@@ -150,9 +239,19 @@ _gdk_window_impl_quartz_get_type (void)
         (GInstanceInitFunc) gdk_window_impl_quartz_init,
       };
       
+      static const GInterfaceInfo paintable_info = 
+      {
+       (GInterfaceInitFunc) gdk_window_impl_quartz_paintable_init,
+       NULL,
+       NULL
+      };
+
       object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_QUARTZ,
                                             "GdkWindowImplQuartz",
                                             &object_info, 0);
+      g_type_add_interface_static (object_type,
+                                  GDK_TYPE_PAINTABLE,
+                                  &paintable_info);
     }
   
   return object_type;
index 0fe45d1f21a0a293428f79b5c3a1122f33ebaec9..1bbc3cd35c0d6835f3ab5a2e8df7be506d8654ca 100644 (file)
@@ -58,6 +58,10 @@ struct _GdkWindowImplQuartz
   NSAutoreleasePool *pool;
 
   NSCursor *nscursor;
+
+  GdkRegion *paint_clip_region;
+  gint begin_paint_count;
+  gint in_paint_rect_count;
 };
  
 struct _GdkWindowImplQuartzClass